//C- -------------------------------------------------------------------
//C- Java DjVu (r) (v. 0.8)
//C- Copyright (c) 2004-2005 LizardTech, Inc.  All Rights Reserved.
//C- Java DjVu is protected by U.S. Pat. No.C- 6,058,214 and patents
//C- pending.
//C-
//C- This software is subject to, and may be distributed under, the
//C- GNU General Public License, Version 2. The license should have
//C- accompanied the software or you may obtain a copy of the license
//C- from the Free Software Foundation at http://www.fsf.org .
//C-
//C- The computer code originally released by LizardTech under this
//C- license and unmodified by other parties is deemed "the LIZARDTECH
//C- ORIGINAL CODE."  Subject to any third party intellectual property
//C- claims, LizardTech grants recipient a worldwide, royalty-free,
//C- non-exclusive license to make, use, sell, or otherwise dispose of
//C- the LIZARDTECH ORIGINAL CODE or of programs derived from the
//C- LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU
//C- General Public License.   This grant only confers the right to
//C- infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to
//C- the extent such infringement is reasonably necessary to enable
//C- recipient to make, have made, practice, sell, or otherwise dispose
//C- of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to
//C- any greater extent that may be necessary to utilize further
//C- modifications or combinations.
//C-
//C- The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
//C- OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
//C- TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
//C- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
//C-
//C- In addition, as a special exception, LizardTech Inc. gives permission
//C- to link the code of this program with the proprietary Java
//C- implementation provided by Sun (or other vendors as well), and
//C- distribute linked combinations including the two. You must obey the
//C- GNU General Public License in all respects for all of the code used
//C- other than the proprietary Java implementation. If you modify this
//C- file, you may extend this exception to your version of the file, but
//C- you are not obligated to do so. If you do not wish to do so, delete
//C- this exception statement from your version.
//C- -------------------------------------------------------------------
//C- Developed by Bill C. Riemers, Foxtrot Technologies Inc. as work for
//C- hire under US copyright laws.
//C- -------------------------------------------------------------------
//
package com.lizardtech.djvu{
import java.io.*;
import java.util.*;


/**
 * DOCUMENT ME!
 *
 * @author $author$
 * @version $Revision: 1.4 $
 */
public class JB2Image
  extends JB2Dict
{
  //~ Instance fields --------------------------------------------------------

  /** DOCUMENT ME! */
  public var reproduce_old_bug:Boolean= false;

  /** DOCUMENT ME! */
  public var height:int= 0;

  /** DOCUMENT ME! */
  public var width:int= 0;
  private var blits:Vector= new Vector();

  //~ Constructors -----------------------------------------------------------

  /**
   * Creates a new JB2Image object.
   */
  public function JB2Image() {}

  //~ Methods ----------------------------------------------------------------

  /**
   * Creates an instance of JB2Image with the options interherited from the
   * specified reference.
   *
   * @param ref Object to interherit DjVuOptions from.
   *
   * @return a new instance of JB2Image.
   */
  public static function createJB2Image(ref:DjVuInterface):JB2Image{
    var options:DjVuOptions= ref.getDjVuOptions();

    return create(
      options,
      options.getJB2ImageClass(),
      "com.lizardtech.djvu.JB2Image") as JB2Image;
  }

  /**
   * DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   */
  public override function clone():Object{
    //DjVuOptions.out.println("1. JB2Image clone");
    var retval:*= JB2Image(super.clone());

    if(this.blits != null)
    {
      var blits:Vector= new Vector();
      (JB2Image(retval)).blits = blits;

      for(var e:Enumeration= this.blits.elements(); e.hasMoreElements();)
      {
        blits.addElement((JB2Blit(e.nextElement())).clone());
      }
    }

    //DjVuOptions.out.println("2. JB2Image clone");
    return retval;
  }

  // overload mapping for as3
  public function get_bitmap(a:*=null, b:*=null, c:*=null, d:*=null, e:*=null):GBitmap {
  	if(a == null) {
  		return get_bitmapA() as GBitmap;
  	} else if((a is int) && (b == null)) {
  		return get_bitmapB(a as int) as GBitmap;
  	} else if((a is int) && (b is int) && (c == null)) {
  		return get_bitmapC(a as int, b as int) as GBitmap;
  	} else if((a is GRect) && (b == null)) {
  		return get_bitmapD(a as GRect) as GBitmap;
  	} else if((a is GRect) && (b is int) && (c == null)) {
  		return get_bitmapE(a as GRect, b as int) as GBitmap;
  	} else if((a is GRect) && (b is int) && (c is int) && (d == null)) {
  		return get_bitmapF(a as GRect, b as int, c as int) as GBitmap;
  	} else if((a is GRect) && (b is int) && (c is int) && (d is int) && (e == null)) {
  		return get_bitmapG(a as GRect, b as int, c as int, d as int) as GBitmap;
  	} else if((a is GRect) && (b is int) && (c is int) && (d is int) && (e is Vector)) {
  		return get_bitmapH(a as GRect, b as int, c as int, d as int, e as Vector) as GBitmap;
  	}
  	return null;
  }

  /**
   * DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   */
  public final function get_bitmapA():GBitmap{
    return get_bitmap(1);
  }

  /**
   * DOCUMENT ME!
   *
   * @param subsample DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   */
  public final function get_bitmapB(subsample:int):GBitmap{
    return get_bitmap(subsample, 1);
  }

  /**
   * DOCUMENT ME!
   *
   * @param subsample DOCUMENT ME!
   * @param align DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   *
   * @throws IllegalStateException DOCUMENT ME!
   */
  public final function get_bitmapC(
    subsample:int,
    align:int):GBitmap{
    if((width == 0) || (height == 0))
    {
      throw new Error("JB2Image can not create bitmap");
    }

    var swidth:int= ((width + subsample) - 1) / subsample;
    var sheight:int= ((height + subsample) - 1) / subsample;
    var border:int= (((swidth + align) - 1) & ~(align - 1)) - swidth;
    var bm:GBitmap= GBitmap.createGBitmap(this);
    bm.init(sheight, swidth, border);
    bm.setGrays(1+ (subsample * subsample));

    for(var blitno:int= 0; blitno < get_blit_count(); blitno++)
    {
      var pblit:JB2Blit= get_blit(blitno);
      var pshape:JB2Shape= get_shape(pblit.shapeno());

      if(pshape.getGBitmap() != null)
      {
        bm.blit(
          pshape.getGBitmap(),
          pblit.left(),
          pblit.bottom(),
          subsample);
      }
    }

    return bm;
  }

  /**
   * DOCUMENT ME!
   *
   * @param rect DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   */
  public final function get_bitmapD(rect:GRect):GBitmap{
    return get_bitmap(rect, 1);
  }

  /**
   * DOCUMENT ME!
   *
   * @param rect DOCUMENT ME!
   * @param subsample DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   */
  public final function get_bitmapE(
    rect:GRect,
    subsample:int):GBitmap{
    return get_bitmap(rect, subsample, 1);
  }

  /**
   * DOCUMENT ME!
   *
   * @param rect DOCUMENT ME!
   * @param subsample DOCUMENT ME!
   * @param align DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   */
  public final function get_bitmapF(
    rect:GRect,
    subsample:int,
    align:int):GBitmap{
    return get_bitmap(rect, subsample, align, 0);
  }

  /**
   * DOCUMENT ME!
   *
   * @param rect DOCUMENT ME!
   * @param subsample DOCUMENT ME!
   * @param align DOCUMENT ME!
   * @param dispy DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   *
   * @throws IllegalStateException DOCUMENT ME!
   */
  public final function get_bitmapG(
    rect:GRect,
    subsample:int,
    align:int,
    dispy:int):GBitmap{
    if((width == 0) || (height == 0))
    {
      throw new Error("JB2Image can not create bitmap");
    }

    var rxmin:int= rect.xmin * subsample;
    var rymin:int= rect.ymin * subsample;
    var swidth:int= rect.width();
    var sheight:int= rect.height();
    var border:int= (((swidth + align) - 1) & ~(align - 1)) - swidth;
    var bm:GBitmap= GBitmap.createGBitmap(this);
    bm.init(sheight, swidth, border);
    bm.setGrays(1+ (subsample * subsample));

    for(var blitno:int= 0; blitno < get_blit_count();)
    {
      var pblit:JB2Blit= get_blit(blitno++);
      var pshape:JB2Shape= get_shape(pblit.shapeno());

      if(pshape.getGBitmap() != null)
      {
        bm.blit(
          pshape.getGBitmap(),
          pblit.left() - rxmin,
          (dispy + pblit.bottom()) - rymin,
          subsample);
      }
    }

    return bm;
  }

  /**
   * DOCUMENT ME!
   *
   * @param rect DOCUMENT ME!
   * @param subsample DOCUMENT ME!
   * @param align DOCUMENT ME!
   * @param dispy DOCUMENT ME!
   * @param components DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   *
   * @throws IllegalStateException DOCUMENT ME!
   */
  public final function get_bitmapH(
    rect:GRect,
    subsample:int,
    align:int,
    dispy:int,
    components:Vector):GBitmap{
    if(components == null)
    {
      return get_bitmap(rect, subsample, align, dispy);
    }

    if((width == 0) || (height == 0))
    {
      throw new Error("JB2Image can not create bitmap");
    }

    var rxmin:int= rect.xmin * subsample;
    var rymin:int= rect.ymin * subsample;
    var swidth:int= rect.width();
    var sheight:int= rect.height();
    var border:int= (((swidth + align) - 1) & ~(align - 1)) - swidth;
    var bm:GBitmap= GBitmap.createGBitmap(this);
    bm.init(sheight, swidth, border);
    bm.setGrays(1+ (subsample * subsample));

    for(var blitno:int= 0; blitno < get_blit_count();)
    {
      var pblit:JB2Blit= get_blit(blitno++);
      var pshape:JB2Shape= get_shape(pblit.shapeno());

      if(pshape.getGBitmap() != null)
      {
        if(
          bm.blit(
            pshape.getGBitmap(),
            pblit.left() - rxmin,
            (dispy + pblit.bottom()) - rymin,
            subsample))
        {
          components.addElement(new Integer(blitno - 1));
        }
      }
    }

    return bm;
  }

  /**
   * DOCUMENT ME!
   *
   * @param blitno DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   */
  public final function get_blit(blitno:int):JB2Blit{
    return blits.elementAt(blitno) as JB2Blit;
  }

  /**
   * DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   */
  public final function get_blit_count():int{
    return blits.size();
  }

  /**
   * DOCUMENT ME!
   *
   * @param blit DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   *
   * @throws IllegalArgumentException DOCUMENT ME!
   */
  public function add_blit(blit:JB2Blit):int{
    if(blit.shapeno() >= get_shape_count())
    {
      throw new IllegalArgumentException("JB2Image bad shape");
    }

    var retval:int= blits.size();

//    blits.addElement(new JB2Blit(blit));
    blits.addElement(blit);

    return retval;
  }

  /**
   * DOCUMENT ME!
   *
   * @param gbs DOCUMENT ME!
   * @param zdict DOCUMENT ME!
   *
   * @throws IOException DOCUMENT ME!
   */
  public override function decode(
    gbs:InputStream, //InputStream,
    zdict:JB2Dict=null):void //JB2Dict
  {
    init();

    var codec:JB2Decode= JB2Decode.createJB2Decode(this);
    codec.init(gbs, zdict);
    codec.code(this);
  }

  /**
   * DOCUMENT ME!
   */
  public override function init():void{
    width = height = 0;
    blits.setSize(0);
    super.init();
  }
}}